/**
 * Copyright @ 2000 ysten Co. Ltd. 
 * All right reserved.     
 * @author: wangmin
 * date: 2016-09-03     
 */
package com.task.service.impl;

import com.task.bean.Constants;
import com.task.service.IRedPackageService;
import com.task.utils.DateTimeUtils;
import com.task.utils.PropertiesUtil;
import com.task.utils.StringUtil;
import com.task.weixin.HttpsRequest;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 发送红包服务
 */
@Service
public class RedPackageServiceImpl implements IRedPackageService {

    public static final String MCH_ID = "mchId";

    private static final Logger LOGGER = LoggerFactory.getLogger(RedPackageServiceImpl.class);
    public static final String MCH_NAME = "mchName";
    public static final String WISHING = "wishing";
    public static final String CLIENT_IP = "clientIp";
    public static final String REMARK = "remark";
    public static final String ACT_NAME = "actName";
    public static final String PAY_API_KEY = "payAPIKey";
    public static final String SENDREDPACKAGEURL = "sendRedPackageUrl";
    public static final String SUCCESS = "SUCCESS";
    public static final String FAIL = "FAIL";


    @Override
    public boolean sendPackage(String openid, Integer money) {
        try {
            if (StringUtils.isNotBlank(openid) && money != null) {
                String billNo = genBillNo();
                LOGGER.info("发送红包，openId:{},红包金额：{}订单号：{}", openid, money, billNo);
                String sendRedPackageUrl = PropertiesUtil.getProperty(SENDREDPACKAGEURL);
                String nonce_str = StringUtil.getRandomCode();
                String sign = sign(openid, String.valueOf(money), billNo,nonce_str);
                String params = "<xml>\n" +
                        "<sign><![CDATA[" + sign + "]]></sign>\n" +
                        "<mch_billno><![CDATA[" + billNo + "]]></mch_billno>\n" +
                        "<mch_id><![CDATA[" + PropertiesUtil.getProperty(MCH_ID) + "]]></mch_id>\n" +
                        "<wxappid><![CDATA[" + PropertiesUtil.getProperty(Constants.CORPID) + "]]></wxappid>\n" +
                        "<send_name><![CDATA[" + PropertiesUtil.getProperty(MCH_NAME) + "]]></send_name>\n" +
                        "<re_openid><![CDATA[" + openid + "]]></re_openid>\n" +
                        "<total_amount><![CDATA[" + money + "]]></total_amount>\n" +
                        "<total_num><![CDATA[1]]></total_num>\n" +
                        "<wishing><![CDATA[" + PropertiesUtil.getProperty(WISHING) + "]]></wishing>\n" +
                        "<client_ip><![CDATA[" + PropertiesUtil.getProperty(CLIENT_IP) + "]]></client_ip>\n" +
                        "<act_name><![CDATA[" + PropertiesUtil.getProperty(ACT_NAME) + "]]></act_name>\n" +
                        "<remark><![CDATA[" + PropertiesUtil.getProperty(REMARK) + "]]></remark>\n" +
                        "<nonce_str><![CDATA[" + nonce_str + "]]></nonce_str>\n" +
                        "</xml>";
                String result = new HttpsRequest().sendPost(PropertiesUtil.getProperty(sendRedPackageUrl), params);
                if (StringUtils.isNotBlank(result)) {
                    StringReader reader = new StringReader(result);
                    SAXReader saxReader = new SAXReader();
                    Document doc = saxReader.read(reader);
                    Element root = doc.getRootElement();
                    String returnCode = root.element("return_code").getTextTrim();
                    if (StringUtils.equals(SUCCESS, returnCode)) {//红包发送成功
                        LOGGER.info("发送红包成功");
                        return true;
                    } else {
                        LOGGER.error("发送红包失败，错误代码：{}，错误原因：{}",root.element("err_code").getTextTrim(),root.element("return_msg").getTextTrim());
                        return false;
                    }
                } else {
                    LOGGER.error("发送红包失败");
                    return false;
                }
            }
        } catch (Exception e) {
            LOGGER.error("send red package error : {}", e);
        }
        return false;
    }

    /**
     * 获取订单号
     *
     * @return
     */
    private String genBillNo() {
        Date now = DateTimeUtils.currentDate();
        StringBuffer result = new StringBuffer();
        result.append(PropertiesUtil.getProperty(MCH_ID));
        String pattern = "yyyyMMdd";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        sdf.setLenient(false);
        String dataFormat = sdf.format(now);
        result.append(dataFormat);
        result.append(("" + System.currentTimeMillis()).substring(3));
        return result.toString();
    }

    /**
     * 生成签名
     *
     * @param openid
     * @param total_amount
     * @param mch_billno
     * @return
     */
    public static String sign(String openid, String total_amount, String mch_billno,String nonceStr) {

        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("wxappid", PropertiesUtil.getProperty(Constants.CORPID));
        parameters.put("mch_id", PropertiesUtil.getProperty(MCH_ID));
        parameters.put("nonce_str", nonceStr);
        parameters.put("mch_billno", mch_billno);
        parameters.put("send_name", PropertiesUtil.getProperty(MCH_NAME));
        parameters.put("total_num", "1");
        parameters.put("wishing", PropertiesUtil.getProperty(WISHING));
        parameters.put("client_ip", PropertiesUtil.getProperty(CLIENT_IP));
        parameters.put("act_name", PropertiesUtil.getProperty(ACT_NAME));
        parameters.put("remark", PropertiesUtil.getProperty(REMARK));
        parameters.put("re_openid", openid);
        parameters.put("total_amount", total_amount);
        String mySign = createSign(parameters);
        LOGGER.info("红包签名：" + mySign);
        return mySign;
    }

    /**
     * 微信支付签名算法sign
     */
    private static String createSign(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照ascii排序（升序）
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + PropertiesUtil.getProperty(PAY_API_KEY));

        LOGGER.info("签名之前的字符串:" + sb.toString());
        String sign = DigestUtils.md5Hex(sb.toString());
        return sign;
    }

/*    public static void main(String[] args) {
        Date now = DateTimeUtils.currentDate();
        StringBuffer result = new StringBuffer();
        result.append(PropertiesUtil.getProperty(MCH_ID));
        String pattern = "yyyyMMdd";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        sdf.setLenient(false);
        String dataFormat = sdf.format(now);
        result.append(dataFormat);
        result.append(("" + System.currentTimeMillis()).substring(3));
        System.out.println(result.toString());
    }*/
}
